#ifndef __OTA_MANAGER_H__
#define __OTA_MANAGER_H__

#include "uc_coding.h"

// OTA最大连续异常次数
#define OTA_MAX_ERROR_CNT (5)
// OTA单包大小
#define OTA_BLOCK_SIZE 512
// OTA起始地址
#define OTA_OP_ADDRESS 0x00000000
// 将某个bit置1
#define SET_BIT(value, bit) (value |= (1 << bit))
// 将某个bit置0
#define CLEAR_BIT(value, bit) (value &= ~(1 << bit))
// 判断某个bit是否为1或0
#define JUDGMENT_BIT(value, bit) (value >> bit & 1)

#define OTA_UPGREADE_COMPLETE_NOTE "upgrade process has end!"
/**
 * @brief HTTP 服务器信息
 *
 */
typedef struct
{
    unsigned int access; /**<  */
    char file_name[32];  /**<  */
    char username[32];   /**< http服务器用户名 */
    char password[32];   /**< http服务器密码 */
    char path[64];       /**<  */
    char address[128];   /**< http服务器地址 */
    unsigned int port;   /**< http端口号 */
} http_info_t;

/**
 * @brief OTA升级时，服务器下发的OTA信息结构体
 *
 */
typedef struct
{
    unsigned int upgrade_type;  /**< 升级类型，整包或差分升级 */
    unsigned int upgrade_range; /**< 升级范围，一般为0，为1时iote_list有效 */
    unsigned int iote_list[8];  /**< 终端的user id，upgrade_range 为1时有效 */
    char new_version[16];       /**< 新版本的版本号 */
    char old_version[16];       /**< 旧版本的版本号 */
    char device_type[12];       /**< 升级的设备类型，gateway或iote */
    char md5[36];               /**< OTA升级包的md5校验值 */
} ota_info_t;

/**
 * @brief OTA升级请求消息结构体
 *
 */
typedef struct
{
    unsigned int active_state; /**< NET连接状态，1表示连接正常，0表示连接异常 */
    ota_info_t ota_info;       /**< OTA升级包信息值 */
    http_info_t http_info;     /**< OTA升级包所在的http服务器信息 */
} ota_upgrade_req_t;

/**
 * @brief OTA升级响应消息结构体，HTTP下载完成后通知manager
 *
 */
typedef struct
{
    unsigned int download_state; /**< OTA升级包下载状态，0表示下载成功，1表示下载失败 */
    unsigned int file_size;      /**< OTA升级包的大小*/
    char file_name[40];          /**< OTA升级包的文件路径，用于升级完成后删除存储在文件系统中的OTA文件 */
} ota_upgrade_res_t;

/**
 * @brief OTA升级完成上报到服务器的信息结构体
 *
 */
typedef struct
{
    char new_version[16]; /**< 新版本的版本号 */
    char old_version[16]; /**< 旧版本的版本号 */
    char device_type[12]; /**< 升级的设备类型iote */
    char note[32];        /**< iote ota upgrade completed */
} ota_upgrade_complete_t;

/**
 * @brief OTA升级流程状态枚举
 *
 */
typedef enum
{
    OTA_STATE_DEFAULE = 0,  /**< OTA初始状态*/
    OTA_STATE_REQ = 1,      /**< OTA升级请求状态*/
    OTA_STATE_RES = 2,      /**< OTA升级下载完成后的响应状态*/
    OTA_STATE_SENDING = 4,  /**< OTA升级包正在发送的状态*/
    OTA_STATE_PROGRAM = 5,  /**< uboot准备OTA升级的状态，只有网关升级有此状态*/
    OTA_STATE_SEND_END = 6, /**< OTA升级包全部发送完成状态*/
    OTA_STATE_STOP = 7      /**< OTA升级完成状态 */
} ota_state_e;

/**
 * @brief 通知终端OTA升级包是否发送完成的状态枚举
 *
 */
typedef enum
{
    OTA_UPGRADE_END = 0, /**< OTA升级包全部发送完成，终端收到此消息将核对数据包是否完成，不完整将发送缺失包请求，完整则升级 */
    OTA_UPGRADING = 1,   /**< OTA正在升级的状态，如果有终端在网关发送升级包的过程中，主动请求升级，将回复此消息 */
    OTA_NOT_UPGRADE = 2, /**< 网关收到OTA主动升级请求核对版本号一样，不需要升级时，回复此消息 */
} ota_upgrade_state_e;

/**
 * @brief OTA包发送的包类型
 *
 */
typedef enum
{
    PACKET_TYPE_UPGRADE_DATA = 0, /**< OTA升级包 */
    PACKET_TYPE_MISSING_DATA = 1, /**< OTA缺失包，OTA升级包发送完成后，将切换位此状态，避免已升级成功的终端重复接收升级包 */
} ota_packet_type_e;

/**
 * @brief OTA状态设置
 *
 * @param state OTA状态，ota_state_e
 */
void manager_set_ota_state(ota_state_e state);

/**
 * @brief 获取OTA状态
 *
 * @return ota_state_e OTA状态
 */
ota_state_e manager_get_ota_state(void);

/**
 * @brief 处理下行OTA升级请求消息
 *
 * @param from_module 来自哪个线程的命令，一般为net
 * @param upgrade_req OTA升级请求消息结构体指针
 */
void manager_handle_ota_upgrade_req_msg(int from_module, ota_upgrade_req_t *upgrade_req);

/**
 * @brief 处理OTA升级响应消息，一般为http将OTA数据包下载完成后的通知消息
 *
 * @param from_module 来自哪个线程的命令，一般为net
 * @param upgrade_res OTA升级响应消息结构体指针
 */
void manager_handle_ota_upgrade_res_msg(int from_module, ota_upgrade_res_t *upgrade_res);

/**
 * @brief 处理OTA数据包发送消息
 *
 */
void manager_handle_ota_upgrade_data_sending_msg(void);

/**
 * @brief 处理终端上报的OTA升级缺失数据请求
 *
 * @param missing_data_req 缺失数据请求消息结构体指针
 */
void manager_handle_missing_data_req_msg(app_ps_missing_data_req_t *missing_data_req);

/**
 * @brief 处理终端OTA升级完成消息
 *
 */
void manager_handle_ota_upgrade_complete_msg(void);

#endif /* __OTA_MANAGER_H__ */
